/**
 * 授权者相关接口
 * @authors 杨兴洲（of2502）
 * @date    2017/3/1 17:45
 * @version 1.0
 */
import {Router} from "express";
import WxAuthorizerService from "../../service/weixin-authorizer-service";
import WxUserService from "../../service/weixin-user-service";
import UserService from "../../service/user-service";
import TokenService from "../../service/token-service";
import LogService from "../../service/log-service";
import ReplyService from "../../service/reply-service";
import logger from "../../util/logger";
import MediaService from "../../service/media-service";
import MCService from "../../service/mc-service";

const router = Router();

/**
 * 绑定Appid & userId
 */
router.post('/bind', (req, res, next) => {
    (async () => {
        try {
            logger.debug(req.body, res.locals);
            const {authCode} = req.body;
            const {userID} = res.locals;
            if (!authCode) {
                return res.status(200).json({
                    errcode: 10001,
                    errmsg: "authCode参数不能为空",
                    userID
                });
            }
            let result = await WxAuthorizerService.queryAuth(authCode);
            const {authorizer_appid, authorizer_access_token, authorizer_refresh_token} = result["authorization_info"];
            // 判断appid是否已经存在其他用户中
            const queryData = await UserService.getInfoByAppID(authorizer_appid);
            if (queryData.userID && queryData.userID !== userID) {
                logger.debug("已存在用户", userID);
                logger.debug("已绑定公众号", authorizer_appid);
                logger.debug("正在请求绑定用户", queryData.userID);
                // 绑定关系 & 存储access_token ( 重新绑定回去 )
                await UserService.setInfo(queryData.userID, {authorizer_appid, authorizer_refresh_token});
                await TokenService.create({userID: queryData.userID, token: authorizer_access_token});
                return res.status(200).json({
                    errcode: 20002,
                    errmsg: "该公众号已经被他人绑定",
                    userID
                });
            }
            // 判断是否是服务号
            const info = await WxAuthorizerService.getAuthorizerInfo(authorizer_appid);
            if (info.authorizer_info.service_type_info.id !== 2) { // 2 服务号
                return res.status(200).json({
                    errcode: 20003,
                    errmsg: "暂不支持订阅号绑定",
                    userID
                });
            }
            //判断是否是微信认证服务号
            if(info.authorizer_info.verify_type_info.id!==0){
                return res.status(200).json({
                    errcode: 20004,
                    errmsg: "暂不支持未认证服务号绑定",
                    userID
                });
            }

            // 绑定关系
            const userInfo = await UserService.setInfo(userID, {authorizer_appid, authorizer_refresh_token});
            const tokenInfo = await TokenService.create({userID, token: authorizer_access_token});
            await ReplyService.setRules({appID: authorizer_appid, rules: {}});// 初始化自动回复列表
            await LogService.create({appID: authorizer_appid, userID, actionType: "authorized"});// 记录日志
            // 同步素材库
            const access_token = await UserService.getAccessToken(userID);
            const {authorizer_appid: appID} = await UserService.getInfo(userID);
            const types = ["image", "voice", "video"];
            await Promise.all(types.map(async type => await MediaService.syncMedia({
                appID, access_token, type, page: 1
            })));
            // MC中心批量关注粉丝
            await MCService.batchAllFollow(userID);

            logger.info(userInfo, tokenInfo);
            res.status(200).json({errcode: 0, errmsg: "公众号绑定成功", userID});
        } catch (error) {
            next(error);
        }
    })();
});


/**
 *
 */


/**
 * 刷新授权码
 * // session 找到用户
 * // => authorizer_appid,authorizer_refresh_token
 * // => post 到腾讯服务器
 */
router.get('/accessToken/update', (req, res, next) => {
    (async () => {
        try {
            const {userID} = res.locals;
            let {authorizer_refresh_token, authorizer_appid} = await UserService.getInfo(userID);
            let {authorizer_access_token} = await WxAuthorizerService.refreshAuthToken({
                authorizer_refresh_token,
                authorizer_appid
            });
            // 存储access_token
            await TokenService.create({userID, token: authorizer_access_token});
            res.status(200).json(authorizer_access_token);
        } catch (error) {
            next(error);
        }
    })();
});

/**
 * 获取授权方基本信息
 */
router.get('/info', (req, res, next) => {
    (async () => {
        try {
            const {userID} = res.locals;
            const {authorizer_appid} = await UserService.getInfo(userID);
            // 判断是否绑定公众号
            if (!authorizer_appid) {
                return res.status(200).json({}); // 不返回错误信息~
                // return res.status(200).json({
                //     errcode: 20001,
                //     errmsg: "该用户还未绑定公众号"
                // });
            }

            let info = await WxAuthorizerService.getAuthorizerInfo(authorizer_appid);
            // 格式处理: todo: 不优雅
            let {nick_name, user_name, alias, head_img, qrcode_url, service_type_info, verify_type_info} = info.authorizer_info;
            let result = {
                nick_name,
                user_name,
                alias,
                head_img,
                qrcode_url,
                service_type_info,
                verify_type_info,
                appid: authorizer_appid,
                userID
            };
            // 增加注释信息
            result.service_type_info.name = result.service_type_info.id === 2 ? "服务号" : "订阅号";
            result.verify_type_info.name = result.verify_type_info.id > -1 ? "已认证" : "未认证";

            res.status(200).json(result);
        } catch (error) {
            next(error);
        }
    })();
});

/**
 * 重置API调用次数
 */
router.post('/reset', (req, res, next) => {
    (async () => {
        try {
            const {userID} = res.locals;
            const access_token = await UserService.getAccessToken(userID);
            const {authorizer_appid} = await UserService.getInfo(userID);
            const data = await WxAuthorizerService.clearQuota({access_token, authorizer_appid});
            res.status(200).json(data);
        } catch (error) {
            next(error);
        }
    })();
});


/**
 * 同步素材库
 */
router.get('/sync', (req, res, next) => {
    (async () => {
        try {
            const {userID} = res.locals;
            const access_token = await UserService.getAccessToken(userID);
            const {authorizer_appid: appID} = await UserService.getInfo(userID);
            const types = ["image", "voice", "video"];
            await Promise.all(types.map(async type => await MediaService.syncMedia({
                appID, access_token, type, page: 1
            })));
            res.status(200).json({errcode: 0, errmsg: "资源库同步成功"});
        } catch (error) {
            next(error);
        }
    })();
});
export default router;
